package com.mscsoft.ui;

import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

import com.mscsoft.App;
import com.mscsoft.musicscore.MusicScore;
import com.mscsoft.tools.ConTools;
import com.mscsoft.tools.GameScore;
import com.mscsoft.tools.ResTools;
import com.mscsoft.tools.ScoreRank;
import com.mscsoft.judge.Judger;

import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.effect.Bloom;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.scene.paint.Paint;
import javafx.stage.Stage;

public class SelectSongsScene extends Application {
    private static Stage stage = new Stage();

    public static Stage getStage() {
        return stage;
    }

    public static void setStage(Stage stage) {
        SelectSongsScene.stage = stage;
    }

    private static List<MusicScore> mss = ResTools.loadMusicScore();

    private static MusicScore curMs = null;

    private int curPage = 1;

    private int totalPage = (int) Math.ceil(mss.size() / 10.0);

    @FXML
    private ImageView background;

    @FXML
    private VBox configPane;

    @FXML
    private HBox defiBox;

    @FXML
    private Label defiText;

    @FXML
    private Label nameLabel;

    @FXML
    private VBox rankListBox;

    @FXML
    private ScrollPane rankListPane;

    @FXML
    private Label scoreLabel;

    @FXML
    private Label scoreText;

    @FXML
    private HBox selectHBox;

    @FXML
    private Pane selectScene;

    @FXML
    private ScrollPane selectSongPane;

    @FXML
    private Button settingButton;

    @FXML
    private HBox songBox;

    @FXML
    private HBox songBox1;

    @FXML
    private HBox songBox2;

    @FXML
    private HBox songBox3;

    @FXML
    private HBox songBox4;

    @FXML
    private HBox songBox5;

    @FXML
    private HBox songBox6;

    @FXML
    private HBox songBox7;

    @FXML
    private HBox songBox8;

    @FXML
    private HBox songBox9;

    @FXML
    private StackPane songImage;

    @FXML
    private Label songLevel;

    @FXML
    private Label songLevel1;

    @FXML
    private Label songLevel2;

    @FXML
    private Label songLevel3;

    @FXML
    private Label songLevel4;

    @FXML
    private Label songLevel5;

    @FXML
    private Label songLevel6;

    @FXML
    private Label songLevel7;

    @FXML
    private Label songLevel8;

    @FXML
    private Label songLevel9;

    @FXML
    private Label songName;

    @FXML
    private Label songName1;

    @FXML
    private Label songName2;

    @FXML
    private Label songName3;

    @FXML
    private Label songName4;

    @FXML
    private Label songName5;

    @FXML
    private Label songName6;

    @FXML
    private Label songName7;

    @FXML
    private Label songName8;

    @FXML
    private Label songName9;

    @FXML
    private Pane songPane;

    @FXML
    private ImageView songRank;

    @FXML
    private ImageView songRank1;

    @FXML
    private ImageView songRank2;

    @FXML
    private ImageView songRank3;

    @FXML
    private ImageView songRank4;

    @FXML
    private ImageView songRank5;

    @FXML
    private ImageView songRank6;

    @FXML
    private ImageView songRank7;

    @FXML
    private ImageView songRank8;

    @FXML
    private ImageView songRank9;

    @FXML
    private Button startButton;

    @FXML
    private HBox userInfo;

    @FXML
    private Label userScoreLabel;

    @FXML
    private VBox buttonBox;

    @FXML
    private Button pageupButton;

    @FXML
    private Button pagedownButton;

    // 选取歌曲列表
    private Label[] songNames;
    private ImageView[] songRanks;
    private Label[] songLevels;

    @FXML
    public void initialize() {
        selectSongPane.setPrefHeight(1000);
        configPane.setPrefHeight(1000);
        configPane.setBackground(new Background(new BackgroundFill(Paint.valueOf("#000"), null, null)));
        inRankImg();
        background.setImage(getBackground());
        List<HBox> songBoxList = Arrays.asList(songBox, songBox1, songBox2, songBox3, songBox4,
                songBox5, songBox6, songBox7, songBox8, songBox9);
        songNames = new Label[] { songName, songName1, songName2, songName3, songName4, songName5, songName6, songName7,
                songName8, songName9 };
        songRanks = new ImageView[] { songRank, songRank1, songRank2, songRank3, songRank4, songRank5, songRank6,
                songRank7, songRank8, songRank9 };
        songLevels = new Label[] { songLevel, songLevel1, songLevel2, songLevel3, songLevel4, songLevel5, songLevel6,
                songLevel7, songLevel8, songLevel9 };

        updatePage();
        for (int i = 0; i < songNames.length; i++) {
            final int t = i;
            songBoxList.get(t).setOnMouseClicked(e -> songBoxClicked(t));
        }
        // 设置按钮样式
        BackgroundImage setButtonImage = new BackgroundImage(
                new Image(getClass().getResourceAsStream("/static/img/SceneComponent/setting.png")),
                BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.CENTER,
                new BackgroundSize(settingButton.getWidth(), settingButton.getHeight(), true, true, true, false));
        Background setButtonBg = new Background(setButtonImage);
        settingButton.setBackground(setButtonBg);
        // 开始按钮样式
        BackgroundImage startButtonImage = new BackgroundImage(
                new Image(getClass().getResourceAsStream("/static/img/SceneComponent/start.png")),
                BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.CENTER,
                new BackgroundSize(startButton.getWidth(), startButton.getHeight(), true, true, true, false));
        Background startButtonBg = new Background(startButtonImage);
        startButton.setBackground(startButtonBg);
        // songImage样式
        BackgroundImage songImageBgImage = new BackgroundImage(
                new Image(getClass().getResourceAsStream("/static/img/SceneComponent/unknown.png")),
                BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.CENTER,
                BackgroundSize.DEFAULT);
        Background songImageBg = new Background(songImageBgImage);
        songImage.setBackground(songImageBg);
        // pageupButton样式
        BackgroundImage pageupButtonImage = new BackgroundImage(
                new Image(getClass().getResourceAsStream("/static/img/SceneComponent/pageup.png")),
                BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.CENTER,
                new BackgroundSize(pageupButton.getWidth(), pageupButton.getHeight(), true, true, true, false));
        Background pageupButtonBg = new Background(pageupButtonImage);
        pageupButton.setBackground(pageupButtonBg);
        pageupButton.setOnMouseClicked(e -> pageupButtonClicked());
        // pagedownButton样式
        BackgroundImage pagedownButtonImage = new BackgroundImage(
                new Image(getClass().getResourceAsStream("/static/img/SceneComponent/pagedown.png")),
                BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.CENTER,
                new BackgroundSize(pagedownButton.getWidth(), pagedownButton.getHeight(), true, true, true, false));
        Background pagedownButtonBg = new Background(pagedownButtonImage);
        pagedownButton.setBackground(pagedownButtonBg);
        pagedownButton.setOnMouseClicked(e -> pagedownButtonClicked());
    }

    @FXML
    private void pagedownButtonClicked() {
        if (curPage < totalPage) {
            curPage++;
            updatePage();
        }
    }

    @FXML
    private void pageupButtonClicked() {
        if (curPage > 1) {
            curPage--;
            updatePage();
        }
    }

    private void updatePage() {
        for (int i = 0; i < songNames.length; i++) {
            int id = getTrueID(i);
            if (id < mss.size()) {
                MusicScore ms = mss.get(id);
                songNames[i].setText(ms.meta.music.title);
                if (!offline) {
                    GameScore gs = ConTools.getBestScore(ms.meta.id);
                    songRanks[i].setImage(gs == null ? null : getSongRank(Judger.getRating(gs.getScore())));
                } else {
                    songRanks[i].setImage(null);
                }
                songLevels[i].setText("" + ms.meta.level);
            } else {
                songNames[i].setText(null);
                songRanks[i].setImage(null);
                songLevels[i].setText(null);
            }
        }
    }

    private int getTrueID(int i) {
        return i + (curPage - 1) * songNames.length;
    }

    private boolean offline = App.getOffline();

    private void songBoxClicked(int boxID) {
        int curID = getTrueID(boxID);
        if (curID >= mss.size())
            return;
        MusicScore getMs = mss.get(curID);
        setCurMs(getMs);
        InputStream imgIS = getClass().getResourceAsStream("/msimg/" + curMs.meta.img);
        Image img = (imgIS != null) ? new Image(imgIS)
                : new Image(getClass().getResourceAsStream("/static/img/SceneComponent/unknown.png"));
        BackgroundImage songImageBgImage = new BackgroundImage(img, BackgroundRepeat.NO_REPEAT,
                BackgroundRepeat.NO_REPEAT, BackgroundPosition.CENTER,
                BackgroundSize.DEFAULT);
        songImage.setBackground(new Background(songImageBgImage));
        // 更新数据
        if (!offline) {
            // 历史最高成绩
            GameScore gs = ConTools.getBestScore(getMs.meta.id);
            userScoreLabel.setText((gs == null) ? "N/A" : "" + gs.getScore());
            // 排行榜
            ScoreRank[] rank = ConTools.getScoreRank(getMs.meta.id);
            StringBuilder nameString = new StringBuilder();
            StringBuilder scoreString = new StringBuilder();
            for (ScoreRank gameScore : rank) {
                nameString.append(gameScore.getName() + "\n");
                scoreString.append(gameScore.getScore() + "\n");
            }
            nameLabel.setText(nameString.toString());
            scoreLabel.setText(scoreString.toString());
        }

        // 点击反馈
        Bloom bloom = new Bloom();
        bloom.setThreshold(0.2);
        songBox.setEffect(bloom);
        // 去除特效
        songBox.setOnMouseExited(e -> songBox.setEffect(null));
    }

    private static void setCurMs(MusicScore ms) {
        curMs = ms;
    }

    private HashMap<String, Image> rankImg = new HashMap<>();

    private void inRankImg() {
        addRankImgFromFile("您", "φ", "V", "S", "A", "B", "C", "D", "F");
    }

    private void addRankImgFromFile(String... rating) {
        for (String s : rating) {
            rankImg.put(s, new Image(Play.class.getResourceAsStream("/static/img/rating/" + s + ".png")));
        }
    }

    private Image getSongRank(String rating) {
        return rankImg.get(rating);
    }

    private Image getBackground() {
        return new Image(getClass().getResourceAsStream("/static/img/SceneComponent/backgroundImage.png"));
    }

    @Override
    @FXML
    public void start(Stage primaryStage) throws Exception {
        setStage(primaryStage);
        Parent root = new FXMLLoader().load(getClass().getResourceAsStream("/fxml/SelectSongsScene.fxml"));
        startButton = (Button) root.lookup("#startButton");
        startButton.setOnAction(e -> startButtonClicked());
        primaryStage.setTitle("SelectSongsScene");
        primaryStage.setScene(new Scene(root, App.getResolutionX(), App.getResolutionY()));
        primaryStage.setOnCloseRequest(e -> System.exit(0));
        primaryStage.show();
    }

    private void startButtonClicked() {
        Play play = new Play();
        try {
            play.setMS(curMs);
            play.start(new Stage());
            stage.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
